#ifndef WOLF_RECT_HPP
#define WOLF_RECT_HPP

#include "common.hpp"
#include <algorithm>

namespace wolf {
using namespace std;
/**
 * @brief Classes that encapsulates the SDL_Rect
 * @ingroup utilMod
 *
 * All its method are inline.
 **/
class Rect {
public:
	/**
	 * @brief Default constructor
	 *
	 *
	 **/
	Rect(void) {
		rect = ( SDL_Rect ) {0, 0, 0, 0};
	}

	/**
	 * @brief Creates a rect
	 *
	 *
	 **/
	Rect(short x, short y, unsigned short w, unsigned short h) {
		rect = ( SDL_Rect ) {x, y, w, h};
	}

	/**
	 * @brief Creates a rect based on an SDL_Rect
	 *
	 *
	 **/
	Rect(const SDL_Rect &rect_) {
		rect = rect_;
	}

	/**
	 * @brief Casts to SDL_Rect
	 *
	 *
	 **/
	SDL_Rect operator()() {
		return rect;
	}

	/**
	 * @brief gets X
	 *
	 *
	 **/
	short getX(void) const {
		return rect.x;
	}

	/**
	 * @brief Gets Y
	 *
	 *
	 **/
	short getY(void) const {
		return rect.y;
	}

	/**
	 * @brief Gets W
	 *
	 *
	 **/
	unsigned short getW(void) const {
		return rect.w;
	}

	/**
	 * @brief Gets H
	 *
	 *
	 **/
	unsigned short getH(void) const {
		return rect.h;
	}

	/**
	 * @brief Gets X2
	 *
	 *
	 **/
	short getX2(void) const {
		return getX() + getW();
	}

	/**
	 * @brief Gets Y2
	 *
	 *
	 **/
	short getY2(void) const {
		return getY() + getH();
	}

	/**
	 * @brief Sets X
	 *
	 *
	 **/
	void setX(short x) {
		rect.x = x;
	}

	/**
	 * @brief Sets Y
	 *
	 *
	 **/
	void setY(short y) {
		rect.y = y;
	}

	/**
	 * @brief Sets W
	 *
	 *
	 **/
	void setW(unsigned short w) {
		rect.w = w;
	}

	/**
	 * @brief Sets H
	 *
	 *
	 **/
	void setH(unsigned short h) {
		rect.h = h;
	}

	/**
	 * @brief Sets X2
	 *
	 *
	 **/
	void setX2(short x2) {
		setW(x2 - getX());
	}

	/**
	 * @brief Sets Y2
	 *
	 *
	 **/
	void setY2(short y2) {
		setH(y2 - getY());
	}

	/**
	 * @brief Returns if it is empty
	 *
	 *
	 **/
	bool empty() {
		return !(rect.w && rect.h);
	}

	/**
	 * @brief Return the intersection
	 *
	 *
	 **/
	const Rect intersection(const Rect &other) {
		Rect r(max(getX(), other.getX()), max(getY(), other.getY()), 0, 0);
		if (getX() < other.getX2() && other.getX() < getX2()
				&& getY() < other.getY2() && other.getY() < getY2()) {
			r.setX2(min(getX2(), other.getX2()));
			r.setY2(min(getY2(), other.getY2()));
		}
		return r;
	}

private:
	SDL_Rect rect;
};
}

#endif // WOLF_RECT_HPP
